package com.xxl.job.executor.service.jobhandler;

import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;

/**
 * XxlJob开发示例（Bean模式）
 *
 * 开发步骤：
 *      1、任务开发：在Spring Bean实例中，开发Job方法；
 *      2、注解配置：为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")"，注解value值对应的是调度中心新建任务的JobHandler属性的值。
 *      3、执行日志：需要通过 "XxlJobHelper.log" 打印执行日志；
 *      4、任务结果：默认任务结果为 "成功" 状态，不需要主动设置；如有诉求，比如设置任务结果为失败，可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果；
 *
 * @author xuxueli 2019-12-11 21:52:51
 */
@Component
public class HttpXxlJob {
    private static ConcurrentHashMap<Object , Object> map = new ConcurrentHashMap<>();
    @Value("${xxl.job.rest.url}")
    private String hpfpUrl ;

    @Value("${xxl.job.rest.connect.timeout}")
    private Integer connectTimeout ;

    @Value("${xxl.job.rest.read.timeout}")
    private Integer readTimeout ;

    /**
     * 跨平台直接调用
     * @throws Exception
     */
    @XxlJob(value="httpJobHandler",init = "init", destroy = "destroy")
    public void httpJobHandler() throws Exception {
        XxlJobHelper.log("------------hpfpUrl:{}" , hpfpUrl) ;
        // param parse
        String param = XxlJobHelper.getJobParam();
        if (param==null || param.trim().length()==0) {
            XxlJobHelper.log("param[{}] invalid." , param);
            XxlJobHelper.handleFail();
            return;
        }
        synchronized (this.getClass()) {
            if (!map.contains(param)) {
                map.put(param, true);
            } else {
                XxlJobHelper.log("param[{}] is running...", param);
                XxlJobHelper.handleFail();
                return;
            }
        }

        // request
        HttpURLConnection connection = null;
        BufferedReader bufferedReader = null;
        try {
            // connection
            URL realUrl = new URL(hpfpUrl.concat(param));
            connection = (HttpURLConnection) realUrl.openConnection();

            // connection setting
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);

            if (readTimeout>0) {
                connection.setReadTimeout(readTimeout * 1000);
            }
            connection.setConnectTimeout(connectTimeout * 1000);
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");

            // do connection
            connection.connect();

            // valid StatusCode
            int statusCode = connection.getResponseCode();
            if (statusCode != 200) {
                throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
            }

            // result
            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result.append(line);
            }
            String responseMsg = result.toString();
            XxlJobHelper.log(responseMsg);
            JSONObject resultJson = JSONObject.parseObject(responseMsg);
            if (!"1".equals(resultJson.getJSONObject("header").getString("code"))) {
                throw new RuntimeException("Http Request Result Exception:\r\n " + responseMsg) ;
            }
            return;
        } catch (Exception e) {
            XxlJobHelper.log(e);

            XxlJobHelper.handleFail();
            return;
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (connection != null) {
                    connection.disconnect();
                }
                map.remove(param) ;
            } catch (Exception e2) {
                XxlJobHelper.log(e2);
            }
        }

    }

    public void init(){
        XxlJobHelper.log("init----------{}" , XxlJobHelper.getJobId());
    }
    public void destroy(){
        XxlJobHelper.log("destroy-----------{}", XxlJobHelper.getJobId());
    }

}
